home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / VGX / envmap / envmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  9.1 KB  |  488 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /*
  18.  *    envmap -
  19.  *        Environment map a spin object in real-time.
  20.  *
  21.  *                   Paul Haeberli - 1990
  22.  */
  23. #include <stdio.h>
  24. #include <sys/types.h>
  25. #include <sys/stat.h>
  26. #include <gl.h>
  27. #include <device.h>
  28. #include <vect.h>
  29.  
  30. #include "ui.h"
  31. #include "fastobj.h"
  32. #include "texture.h"
  33. #include "envmap.h"
  34.  
  35. /****************************************************************************/
  36.  
  37. char *ProgName = 0;
  38. char StrOption[] = "DW:b:fe:t:?";
  39. char StrUsage[] = "[-Df] [-W x0,y0[,x1,y1] [-b ModelName] [-e EnvName] [-t TextureName]";
  40.  
  41. long Xorigin, Yorigin, Xsize, Ysize;
  42. int UsePrefsize = 0;
  43. int UsePrefposition = 0;
  44.  
  45. #define SHADE_INFINITE    0
  46. #define SHADE_LOCAL    1
  47.  
  48. int debugmode = 0;
  49. int fullscreenmode = 0;
  50.  
  51. int dotrans = 0;
  52. int solidtex = 0, transtex = 0;
  53.  
  54. int shadehow = SHADE_INFINITE;
  55.  
  56. fastobj *obj;
  57.  
  58. char envname[200];
  59. char transenvname[200];
  60. char modelname[200];
  61.  
  62. settrans(trans)
  63. int trans;
  64. {
  65.     if(trans) {
  66.         settexture(transtex);
  67.         blendfunction(BF_ONE,BF_ONE);
  68.         zfunction(ZF_ALWAYS);
  69.     } else {
  70.         settexture(solidtex);
  71.         blendfunction(BF_ONE,BF_ZERO);
  72.         zfunction(ZF_LEQUAL);
  73.     }
  74. }
  75.  
  76. clearscreen()
  77. {
  78.     zclear();
  79.     if(dotrans) {
  80.         backface(0);
  81.         RGBcolor(0,0,0);
  82.     } else {
  83.         backface(0);
  84.         RGBcolor(0,0,0);
  85.     }
  86.     clear();
  87. }
  88.  
  89. static void Usage()
  90. {
  91.     fprintf(stderr, "usage: %s %s\n", ProgName, StrUsage);
  92. }
  93.  
  94. docmdline(argc, argv)
  95.     int argc;
  96.     char **argv;
  97. {
  98.     int opt;
  99.     struct stat buf;
  100.     extern char *optarg;
  101.     extern int getopt();
  102.  
  103.     while ((opt = getopt(argc, argv, StrOption)) != -1) {
  104.     switch(opt) {
  105.       case '?':
  106.         Usage();
  107.         exit(1);
  108.  
  109.       case 'D': 
  110.           debugmode ^= 1;
  111.           printf("debugmode=%d\n",debugmode);
  112.           break;
  113.  
  114.       case 'W': /* provide x1,y1,x2,y2  or just xsize, ysize */
  115.         if (4 == sscanf(optarg, "%d,%d,%d,%d", &Xorigin, &Yorigin, 
  116.         &Xsize, &Ysize)) {
  117.         UsePrefposition = 1;
  118.         } else if (2 == sscanf(optarg, "%d,%d", &Xsize, &Ysize)) {
  119.         UsePrefsize = 1;
  120.         } else  {
  121.         Usage();
  122.         exit(-1);
  123.         }
  124.         break;
  125.  
  126.       case 'f': 
  127.           fullscreenmode ^= 1;
  128.           printf("fullscreenmode=%d\n",fullscreenmode);
  129.           break;
  130.  
  131.       case 't':
  132.         if (optarg[0] == '/') {
  133.         strcpy(transenvname, optarg);
  134.         } else {
  135.         if (stat(optarg, &buf) == 0) {
  136.             strcpy(transenvname, optarg);
  137.         } else {
  138.             strcpy(transenvname, TEXDIR);
  139.             strcat(transenvname, optarg);
  140.         }
  141.         }
  142.         fprintf(stderr, "transparent environment map is %s\n",
  143.         transenvname);
  144.         transtex = 2;
  145.         dotrans = 1;
  146.         break;
  147.  
  148.       case 'b':
  149.         if (optarg[0] == '/') {
  150.         strcpy(modelname, optarg);
  151.         } else {
  152.         if (stat(optarg, &buf) == 0) {
  153.             strcpy(modelname, optarg);
  154.         } else {
  155.             strcpy(modelname, MODELDIR);
  156.             strcat(modelname, optarg);
  157.         }
  158.         }
  159.         if (!(obj = readfastobj(modelname))) {
  160.         fprintf(stderr, "envmap: can't read %s\n", modelname);
  161.         exit(1);
  162.         }
  163.         break;
  164.  
  165.       case 'e':
  166.         if (optarg[0] == '/') {
  167.         strcpy(envname, optarg);
  168.         } else {
  169.         if (stat(optarg, &buf) == 0) {
  170.             strcpy(envname, optarg);
  171.         } else {
  172.             strcpy(envname, ENVDIR);
  173.             strcat(envname, optarg);
  174.         }
  175.         }
  176.         solidtex = 1;
  177.         transtex = 1;
  178.         fprintf(stderr, "solid environment map is %s\n", envname);
  179.         break;
  180.  
  181.       default:
  182.         fprintf(stderr, "usage: envmap object map.env [trans.env]\n");
  183.         exit(1);
  184.         break;
  185.     }
  186.     }
  187.     if (!obj) {
  188.     fprintf(stderr, "envmap: no bin file given!\n");
  189.     exit(1);
  190.     }
  191.     if (!solidtex) {
  192.     fprintf(stderr, "envmap: no environment file given!\n");
  193.     exit(1);
  194.     }
  195. }
  196.  
  197. #define ZTRANS (-1.6)
  198.  
  199. static float s_axis[3] = { 0.5, 1.0, 0.0};
  200. static float spin[4] = { 0.0, 0.0, 0.0, 1.0};
  201. static float total_rotation[4] = { 0.0, 0.0, 0.0, 1.0};
  202. static float pos[3] = { 0.0, 0.0, ZTRANS};
  203. static int spinning = FALSE;
  204.  
  205. void
  206. draw_object()
  207. {
  208.     Matrix m;
  209.  
  210.     clearscreen();
  211.  
  212.     pushmatrix();
  213.  
  214.     translate(pos[0], pos[1], pos[2]);
  215.     build_rotmatrix(m, total_rotation);
  216.     multmatrix(m);
  217.  
  218.     if (dotrans) cpack(0x80808080);
  219.     else cpack(0xFFFFFFFF);
  220.     drawenvobj(obj, m);
  221.  
  222.     popmatrix();
  223.  
  224.     swapbuffers();
  225. }
  226.  
  227. /*
  228.  *    Called by ui interface, passed a float[4] that is a rotation
  229.  * specified in Euler paramaters and a float[3] that is xyz
  230.  * translation.  (no rotation is {0.0, 0.0, 0.0, 1.0}, no translation
  231.  * is {0.0, 0.0, 0.0})
  232.  */
  233. void
  234. remember_view(float *rot, float *trans)
  235. {
  236.     vcopy(rot, spin);
  237.     spin[3] = rot[3];
  238.     vadd(trans, pos, pos);
  239.  
  240.     add_quats(spin, total_rotation, total_rotation);
  241.  
  242.     draw_object();
  243. }
  244.  
  245. void
  246. spin_scene()
  247. {
  248.     add_quats(spin, total_rotation, total_rotation);
  249.  
  250.     draw_object();
  251. }
  252.  
  253. void
  254. redraw_scene()    /* Called when aspect ratio might change */
  255. {
  256.     float aspect;
  257.     long xdim, ydim;
  258.  
  259.     getsize(&xdim,&ydim);
  260.     aspect = (float) xdim/(float) ydim;
  261.     perspective(450,aspect,0.1,100.0);
  262.  
  263.     draw_object();
  264. }
  265.  
  266. void
  267. anything_moving(int *flag)
  268. {
  269.     if (spin[0] == 0.0 && spin[1] == 0.0 && spin[2] == 0.0)
  270.         (*flag) = FALSE;
  271.     else (*flag) = TRUE;
  272. }
  273.  
  274. static long menu = (-1);
  275.  
  276. void
  277. build_menu()
  278. {
  279.     if (menu != (-1)) freepup(menu);
  280.  
  281.     menu = newpup();
  282.     addtopup(menu, "Environment Map %t");
  283.     if (!dotrans)
  284.         addtopup(menu, "Transparent Model %x1");
  285.     else
  286.         addtopup(menu, "Solid Model %x2");
  287.     if (shadehow == SHADE_LOCAL)
  288.         addtopup(menu, "Infinite Viewer %x3");
  289.     else
  290.         addtopup(menu, "Local Viewer %x4");
  291.     addtopup(menu, "Reset %x5");
  292.     addtopup(menu, "Exit %x6");
  293. }
  294. void
  295. do_menu()
  296. {
  297.     int needredraw = 0;
  298.     
  299.     switch (dopup(menu))
  300.     {
  301.         case 1:    /* Transparent model */
  302.             dotrans = 1;
  303.             settrans(dotrans);
  304.             needredraw=1;
  305.             break;
  306.         case 2:    /* Solid model */
  307.             dotrans = 0;
  308.             settrans(dotrans);
  309.             needredraw=1;
  310.             break;
  311.         case 3:    /* Infinite viewer */
  312.             shadehow = SHADE_INFINITE;
  313.             needredraw=1;
  314.             break;
  315.         case 4:    /* Local viewer */
  316.             shadehow = SHADE_LOCAL;
  317.             needredraw=1;
  318.             break;
  319.         case 5:    /* Reset */
  320.             vzero(pos); pos[2] = ZTRANS;
  321.             vzero(total_rotation);
  322.             total_rotation[3] = 1.0;
  323.             vzero(spin);
  324.             spin[3] = 1.0;
  325.             spinning = FALSE;
  326.             shadehow = SHADE_INFINITE;
  327.             dotrans = 0;
  328.             needredraw=1;
  329.             break;
  330.         case 6:
  331.             ui_exit();
  332.             break;
  333.     }
  334.     if (needredraw)
  335.     {
  336.         build_menu();
  337.         qenter(REDRAW,1);
  338.     }
  339. }
  340.  
  341. main(argc,argv)
  342. int argc;
  343. char **argv;
  344. {
  345.     float aspect;
  346.     long xdim, ydim;
  347.     short val;
  348.  
  349.     docmdline(argc, argv);
  350.  
  351.     if (debugmode)
  352.         foreground();
  353.  
  354.     if (UsePrefsize)
  355.         prefsize(Xsize, Ysize);
  356.     else if (UsePrefposition)
  357.         prefposition(Xorigin, Xorigin + Xsize - 1, 
  358.             Yorigin, Yorigin + Ysize - 1);
  359.     else if (fullscreenmode)
  360.         prefposition(0, XMAXSCREEN, 0, YMAXSCREEN);
  361.  
  362.     /* Open with the executable's name (stripped of directory) */
  363.     {
  364.         char *t, *strrchr(char *, int);
  365.         winopen((t=strrchr(argv[0], '/')) != NULL ? t+1 : argv[0]);
  366.     }
  367.  
  368.     subpixel(TRUE);
  369.     doublebuffer();
  370.     RGBmode();
  371.     gconfig();
  372.  
  373.     build_menu();
  374.  
  375.     textureread(envname, solidtex, 4, 0);
  376.     if (dotrans) {
  377.         textureread(transenvname, transtex, 4, 0);
  378.     }
  379.     settrans(dotrans);
  380.  
  381.     zbuffer(TRUE);
  382.     mmode(MVIEWING);
  383.  
  384.     getsize(&xdim,&ydim);
  385.     aspect = (float) xdim/(float) ydim;
  386.     perspective(450,aspect,0.1,100.0);
  387.  
  388.     add_event(ANY, RIGHTMOUSE, DOWN, do_menu, NULL);
  389.     qdevice(RIGHTMOUSE);
  390.     add_event(ANY, ESCKEY, UP, ui_exit, NULL);
  391.     qdevice(ESCKEY);
  392.     add_event(ANY, WINQUIT, ANY, ui_exit, NULL);
  393.     qdevice(WINQUIT);
  394.     add_event(ANY, REDRAW, ANY, redraw_scene, NULL);
  395.     qdevice(REDRAW);
  396.  
  397.     add_update(&spinning, spin_scene, NULL);
  398.      add_event(ANY, ANY, ANY, anything_moving, (unsigned char *)&spinning);
  399.  
  400.     axis_to_quat(s_axis, 0.1, spin);
  401.  
  402.     qenter(REDRAW, 1);
  403.     ui(remember_view);
  404.     gexit();
  405.     exit(0);
  406. }
  407.  
  408. xformvect(matrix,v,tv)
  409. float matrix[4][4];
  410. float *v, *tv;
  411. {
  412.     tv[0] = v[0]*matrix[0][0] + v[1]*matrix[1][0] + v[2]*matrix[2][0];
  413.     tv[1] = v[0]*matrix[0][1] + v[1]*matrix[1][1] + v[2]*matrix[2][1];
  414.     tv[2] = v[0]*matrix[0][2] + v[1]*matrix[1][2] + v[2]*matrix[2][2];
  415. }
  416.  
  417. #define TMDIV    2.1
  418.  
  419. tmnorm(n,p,mat)
  420. float *n, *p;
  421. float mat[4][4];
  422. {
  423.     float eye[3], tn[3], tp[3], tex[3];
  424.     float ref[3], ahead[3], half[3], c[3];
  425.     float col[3];
  426.  
  427.     switch(shadehow) {
  428.         case SHADE_INFINITE:
  429.             xformvect(mat,n,tn);
  430.             if(tn[2]<0.0) {
  431.                 tn[0] = -tn[0];
  432.                 tn[1] = -tn[1];
  433.                 tn[2] = -tn[2];
  434.             }
  435.             tex[0] = 0.5+tn[0]/TMDIV;
  436.             tex[1] = 0.5+tn[1]/TMDIV;
  437.             t2f(tex);
  438.             break;
  439.         case SHADE_LOCAL:
  440.             xformvect(mat,n,tn);
  441.             if(tn[2]<0.0) {
  442.                 tn[0] = -tn[0];
  443.                 tn[1] = -tn[1];
  444.                 tn[2] = -tn[2];
  445.             }
  446.             xformvect(mat,p,tp);
  447.             vadd(tp, pos, tp);
  448.             vcopy(tp, eye);
  449.             vnormal(eye);
  450.             vreflect(eye,tn,ref);
  451.             ahead[0] = 0.0;
  452.             ahead[1] = 0.0;
  453.             ahead[2] = -1.0;
  454.             vhalf(ref,ahead,half);
  455.             tex[0] = 0.5-(half[0]/TMDIV);
  456.             tex[1] = 0.5-(half[1]/TMDIV);
  457.             t2f(tex);
  458.             break;
  459.     }
  460. }
  461.  
  462. drawenvobj(obj,mat)
  463. fastobj *obj;
  464. float mat[4][4];
  465. {
  466.     register float *p;
  467.     register int npolys;
  468.  
  469.     npolys = obj->npoints/4;
  470.     p = (float *)obj->data;
  471.     while(npolys--) {
  472.     bgnpolygon();
  473.     tmnorm(p,p+4,mat);
  474.     v3f(p+4);
  475.     p += 8;
  476.     tmnorm(p,p+4,mat);
  477.     v3f(p+4);
  478.     p += 8;
  479.     tmnorm(p,p+4,mat);
  480.     v3f(p+4);
  481.     p += 8;
  482.     tmnorm(p,p+4,mat);
  483.     v3f(p+4);
  484.     p += 8;
  485.     endpolygon();
  486.     }
  487. }
  488.